﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Xml.Serialization;
using System.Xml;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace BPMS.Utility.Serializer
{
    public class SerializeUtility
    {
        /// <summary>对象转化成二进制 </summary>
        public static byte[] BinarySerialize<T>(T item) where T : ISerializable
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(memoryStream, item);
                return memoryStream.ToArray();
            }
        }
        /// <summary>对象转化成二进制并保存成文件 </summary>
        public static void BinarySerialize<T>(T item, string fileName) where T : ISerializable
        {
            using (Stream stream = File.Open(fileName, FileMode.Create))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(stream, item);
                stream.Close();
            }
        }
        /// <summary>二进制转化成对象 </summary>
        public static T BinaryDeserialize<T>(byte[] data) where T : ISerializable
        {
            using (MemoryStream stream = new MemoryStream(data))
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                stream.Seek(0, SeekOrigin.Begin);
                T item = (T)binaryFormatter.Deserialize(stream);
                stream.Close();
                return item;
            }
        }
        /// <summary>序列化对象</summary>
        public static string XmlSerialize<T>(T item, bool removeNamespaces)
        {
            object locker = new object();
            XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
            xmlns.Add(string.Empty, string.Empty);
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            XmlWriterSettings settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
            lock (locker)
            {
                StringBuilder stringBuilder = new StringBuilder();
                using (StringWriter stringWriter = new StringWriter(stringBuilder))
                {
                    using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
                    {
                        if (removeNamespaces)
                            xmlSerializer.Serialize(xmlWriter, item, xmlns);
                        else
                            xmlSerializer.Serialize(xmlWriter, item);
                        return stringBuilder.ToString();
                    }
                }
            }
        }
        /// <summary>反序列化字串到对象</summary>
        public static T XmlDeserialize<T>(string s)
        {
            object locker = new object();
            StringReader stringReader = new StringReader(s);
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
            lock (locker)
            {
                using (XmlTextReader reader = new XmlTextReader(stringReader))
                {
                    T item = (T)xmlSerializer.Deserialize(reader);
                    reader.Close();
                    return item;
                }
            }
        }

        /// <summary>
        /// JSON序列化为字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="item"></param>
        /// <returns></returns>
        public static string JsonSerialize<T>(T item)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            using (MemoryStream stream = new MemoryStream())
            {
                serializer.WriteObject(stream, item);
                return Encoding.UTF8.GetString(stream.ToArray());
            }
        }

        /// <summary>
        /// JSON字符串反序列化为对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="json"></param>
        /// <returns></returns>
        public static T JsonDeSerialize<T>(string json)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            byte[] buffer = Encoding.UTF8.GetBytes(json);
            using (MemoryStream stream = new MemoryStream(buffer))
            {
                return (T)serializer.ReadObject(stream);
            }
        }

        /// <summary>深克隆 </summary>
        public static T DeepClone<T>(T item) where T : ISerializable
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                BinaryFormatter binaryFormatter = new BinaryFormatter();
                binaryFormatter.Serialize(memoryStream, item);
                memoryStream.Seek(0, SeekOrigin.Begin);
                return (T)binaryFormatter.Deserialize(memoryStream);
            }
        }
    }
}
